<?php
/**
 * 监狱
 * 
 * Created	: 2011-11-10
 * Modified : 2011-11-10
 * @author  : 陈立强
 */
class Prison
{
	
	public static $cfg = null;
	public static $cfgName = 'build/prison';
	
	/**
	 * 收押一个玩家
	 * @param int $uid
	 * @param int $type
	 */
	public static function detain($uid, $type=1) 
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT id FROM prison WHERE uid='.$uid;
		$exist = $DB->getValue($sql);
		if ($exist) {
			return false;
		}
		
		$now = time();
		
		$typeAttr = $G['type_attr'][$type];
		
		$DB->beginTransaction();
		
		$data = array(
			'uid'				=> $uid,
			'nickname'			=> User::getNickname($uid),
			'type'				=> $type,
			'nasty_value'		=> $typeAttr['nasty_value'],
			'can_escape'		=> $typeAttr['can_escape'],
			'can_bribe'			=> $typeAttr['can_bribe'],
			'can_help_bribe'	=> $typeAttr['can_help_bribe'],
			'can_interactive'	=> $typeAttr['can_interactive'],
			'can_chat'			=> $typeAttr['can_chat'],
			'can_login'			=> $typeAttr['can_login'],
			'put_in_time'		=> $now,
			'escape_times'		=> 0,
			'next_escape_time'	=> 0,
			'status'			=> 1,
		);
		
		$sql = 'SELECT id FROM prison WHERE status=0';
		$exist = $DB->getValue($sql);
		if ($exist) {
			$ret = $DB->update('prison', $data, 'id='.$exist);
			$prison_id = $exist;
		} else {
			$return = $DB->insert('prison', $data);
			$ret = $return['val'];
			$prison_id = $DB->lastInsertId();
		}
		
		// 记录监狱信息
		if ($ret) {
			$content = $L['prison_type_note'][$type];
			$ret = self::note($uid, $prison_id, $content);
		}
		
		// 更改用户是否在监狱字段
		if ($ret) {
			$sql = 'UPDATE user SET in_prison='.$prison_id.' WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
			if ($ret !== false) {
				$ret = true;
			}
		}
		
		
		if ($ret) {
			// 处理成功,提交事务
			$DB->commit();
		} else {
			// 出错,回滚数据操作
			$DB->rollBack();
			$data = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('prison_detain', $data);
		}

		return (boolean)$ret;
	}
	
	/**
	 * 获取监狱中的犯人列表
	 * @param $uid
	 */
	public static function getList($uid) 
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT * FROM prison WHERE status=1';
		$list = $DB->getList($sql);
		
		return array(
			'val'  => true,
			'data' => $list
		);
	}
	
	/**
	 * 记录一个监狱位置的信息
	 * @param int $uid
	 * @param int $prison_id
	 */
	public static function note($uid, $prison_id, $content) 
	{
		global $DB, $L, $G;
		
		$DB->beginTransaction();
		
		$data = array(
			'prison_id'	=> $prison_id,
			'uid'		=> $uid,
			'nickname'	=> User::getNickname($uid),
			'content'	=> $content
		);
		$ret = $DB->insert('prison_note', $data);
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			// 处理成功,提交事务
			$DB->commit();
		} else {
			// 出错,回滚数据操作
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$data = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('prison_note', $data);
		}

		return (boolean)$result;
	}
	
	/**
	 * 探视
	 * @param int $uid
	 * @param int $prison_id
	 */
	public static function visit($uid, $prison_id) 
	{
		global $DB, $L, $G;
		
		$prison_id = (int)$prison_id;
		$sql = 'SELECT * FROM prison WHERE id='.$prison_id;
		$prisonInfo = $DB->getValue($sql);
		if (!$prisonInfo['status']) {
			return array(
				'val'  => false,
				'msg' => $L['prisoner_not_exist']
			);
		}
		
		$sql = 'SELECT * FROM prison_note WHERE prison_id='.$prison_id;
		$noteList = $DB->getList($sql);
		
		$result = array(
			'val' 				=> true,
			'prison_info'		=> $prisonInfo,
			'prison_note_list'	=> $noteList,
		);

		return $result;
	}
	
	/**
	 * 越狱
	 * @param int $uid
	 * @param int $prison_id
	 * @param boolean $first true-表示正准备越狱还未选择选项
	 */
	public static function escape($uid, $prison_id, $first=0, $option=null) 
	{
		global $DB, $L, $G;
		
		$prison_id = (int)$prison_id;
		$option = (int)$option;
		
		$sql = 'SELECT * FROM prison WHERE id='.$prison_id;
		$prisonInfo = $DB->getValue($sql);
		if (!$prisonInfo) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		// 只能自己进行越狱
		else if ($prisonInfo['uid'] != $uid) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
		
		$now = time();
		
		// 未到冷却时间
		if ($prisonInfo['next_escape_time'] > $now) {
			return array(
				'val' => false,
				'msg' => $L['escape_prison_cd_time_not_end']
			);
		}
		
		$DB->beginTransaction();
		
		if ($first) {
			if ($prisonInfo['status']==0) {
				return array(
					'val' => false,
					'msg' => $L['invalid_request']
				);
			}
			$sql = 'SELECT id,options FROM prison_escape WHERE prison_id='.$prison_id;
			$exist = $DB->getValue($sql);
			if ($exist) {
				$exist['options'] = json_decode($exist['options'], true);
				foreach ($exist['options'] as $id=>$v) {
					$exist['options'][$id] = $G['escape_option'][$id];
				}
				return array(
					'val'	=> false,
					'msg'	=> $L['escape_prison_note_is_exist'],
					'data'	=> $exist
				);
			}
			$handleTimes = $G['escape_base_times'] + $prisonInfo['nasty_value'] * $G['escape_param'];
			$newOption = self::generateOption();;
			$returnOption = $newOption[1];
			$data = array(
				'prison_id'		=> $prison_id,
				'uid'			=> $uid,
				'nickname'		=> User::getNickname($uid),
				'escape_time'	=> $now,
				'handle_times'	=> $handleTimes,
				'now_times'		=> 0,
				'alarm_value'	=> 0,
				'options'		=> json_encode($newOption[0]),
				'status'		=> 0,
			);
			$ret = $DB->insert('prison_escape', $data);
			$result['data'] = array(
				'options' => $returnOption
			);
		} else {
			$sql = 'SELECT * FROM prison_escape WHERE prison_id='.$prison_id;
			$info = $DB->getValue($sql);
			$info['options'] = json_decode($info['options'], true);
			
			// 已经被看守发现,不能越狱
			if ($info['status'] == 1) {
				return array(
					'val'	=> false,
					'msg'	=> $L['cannot_escape_when_be_found']
				);
			}
			
			// 传回服务器的选项参数非法
			if (isset($info['options'][$option])) {
				$info['alarm_value'] += $info['options'][$option];
			} else {
				return array(
					'val' => false,
					'msg' => $L['invalid_request']
				);
			}
			
			if ($info['alarm_value'] < 0) {
				$info['alarm_value'] = 0;
			}
			// 达到警报值被看守发现
			else if ($info['alarm_value'] >= $G['max_alarm_value']) {
				$data = array(
					'alarm_value'	=> $G['max_alarm_value'],
					'status'		=> 1,
				);
				$ret = $DB->update('prison_escape', $data, 'prison_id='.$prison_id);
				
				// 被看守发现直接暂停当前越狱进程
				if ($ret) {
					$DB->commit();
					return array(
						'val'	=> true,
						'data'	=> array(
							'be_found'	=> true,
						),
					);
				} else {
					// 出错,回滚数据操作
					$DB->rollBack();
					$result['msg'] = $L['Failure'];
					$data = var_export($DB->errors, true);
					// 记录错误日志
					Log::save('prison_escape', $data);
				}
			} else {
				
			}
			
			$now_times = $info['now_times'] + 1;
			// 越狱闯关次数已完成(越狱成功)
			if ($info['handle_times'] == $now_times) {
				$ret = self::escapeSuccess($uid, $prison_id);
			} else {
				$newOption = self::generateOption();;
				$returnOption = $newOption[1];
				$data = array(
					'alarm_value'	=> $info['alarm_value'],
					'now_times'		=> $now_times,
					'options'		=> json_encode($newOption[0])
				);
				$ret = $DB->update('prison_escape', $data, 'prison_id='.$prison_id);
				$result['data'] = array(
					'options' => $returnOption
				);
			}
		}
		
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			// 处理成功,提交事务
			$DB->commit();
		} else {
			// 出错,回滚数据操作
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$data = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('prison_escape', $data);
		}
		
		return $result;
	}
	
	/**
	 * 生成选项
	 */
	private static function generateOption()
	{
		global $G;
		$option = array();
		$returnOption = array();
		for ($i=0; $i<3; $i++) {
			$value = rand(1, 3) - 2;
			$optionId = array_rand($G['escape_option']);
			$option[$optionId] = $value;
			$returnOption[$optionId] = $G['escape_option'][$optionId];
			unset($G['escape_option'][$optionId]);
		}
		return array(
			$option,
			$returnOption
		);
	}
	
	/**
	 * 贿赂
	 * @param int $uid
	 * @param int $prison_id
	 */
	public static function bribe($uid, $prison_id) 
	{
		global $DB, $L, $G;
		
		$prison_id = (int)$prison_id;
		$sql = 'SELECT * FROM prison WHERE id='.$prison_id;
		$prisonInfo = $DB->getValue($sql);
		if (!$prisonInfo || $prisonInfo['status']==0) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		} else if ($prisonInfo['status'] != 1) {
			return array(
				'val' => false,
				'msg' => $L['prisoner_not_be_found']
			);
		}
		
		$sql = 'SELECT * FROM prison_escape WHERE prison_id='.$prison_id;
		$prisonEscapeInfo = $DB->getValue($sql);
		if ($prisonEscapeInfo['status'] != 1) {
			return array(
				'val' => false,
				'msg' => $L['invalid_request']
			);
		}
	
		$user = User::read($uid);
		$needCoin = $G['bribe_need_base_coin'] 
						+ ($prisonInfo['nasty_value'] * $G['bribe_need_coin_param']);
		// 需要金钱不足
		if ($user['coin'] < $needCoin) {
			return array(
				'val' => false,
				'msg' => $L['coin_not_enough']
			);
		}
		
		// 贿赂成功率
		$rate = $G['bribe_base_rate'] - $prisonInfo['nasty_value'];
		if ($rate < $G['bribe_min_rate']) {
			$rate = $G['bribe_min_rate'];
		}
		
		$success = getRandResult($rate);
		
		$DB->beginTransaction();
		
		// 贿赂成功
		if ($success) {
			$newOption = self::generateOption();;
			$returnOption = $newOption[1];
			if ($prisonEscapeInfo['now_times'] < $prisonEscapeInfo['handle_times']) {
				$prisonEscapeInfo['now_times'] ++;
			}
			// 贿赂成功后同时越狱次数已满,直接越狱成功
			if ($prisonEscapeInfo['now_times'] == $prisonEscapeInfo['handle_times']) {
				$ret = self::escapeSuccess($uid, $prison_id);
			} else {
				$data = array(
					'now_times'		=> $prisonEscapeInfo['now_times'],
					'alarm_value'	=> $G['bribe_success_alarm_value'],
					'options'		=> json_encode($newOption[0]),
					'status'		=> 0,
				);
				$ret = $DB->update('prison_escape', $data, 'prison_id='.$prison_id);
			}
		}
		// 贿赂失败
		else {
			$ret = self::escapeFailure($uid, $prison_id);
		}
		
		// 扣除金钱
		$sql = 'UPDATE user SET coin=coin-'.$needCoin.' WHERE uid='.$uid;
		$ret = $DB->exeSql($sql);
		
		
		$result['val'] = (boolean)$ret;
		if ($ret) {
			// 处理成功,提交事务
			$DB->commit();
			$result['data'] = array(
				'need_coin'	=> $needCoin,
				'success'	=> $success,
			);
			if ($success) {
				$result['data']['options'] = $returnOption;
			}
		} else {
			// 出错,回滚数据操作
			$DB->rollBack();
			$result['msg'] = $L['Failure'];
			$data = var_export($DB->errors, true);
			// 记录错误日志
			Log::save('prison_bribe', $data);
		}

		
		return $result;
	}
	
	/**
	 * 束手就擒
	 * @param $uid
	 * @param $prison_id
	 */
	public static function beSeized($uid, $prison_id) 
	{
		global $DB, $L, $G;
		
		$ret = self::escapeFailure($uid, $prison_id);
		
		return array(
			'val'	=> (boolean)$ret,
		);
	}
	
	/**
	 * 处理越狱成功
	 * @param int $uid
	 * @param int $prison_id
	 */
	private static function escapeSuccess($uid, $prison_id) 
	{
		global $DB, $L, $G;
		
		$where = 'prison_id='.$prison_id;
		$ret = $DB->delete('prison_escape', $where);
		if ($ret) {
			$ret = $DB->delete('prison_note', $where);
			if ($ret !== false) {
				$ret = true;
			}
		}
		if ($ret) {
			$data = array(
				'uid'				=> 0,
				'nickname'			=> '',
				'type'				=> 0,
				'nasty_value'		=> 0,
				'can_escape'		=> 0,
				'can_bribe'			=> 0,
				'can_help_bribe'	=> 0,
				'can_interactive'	=> 0,
				'can_chat'			=> 0,
				'can_login'			=> 0,
				'put_in_time'		=> 0,
				'escape_times'		=> 0,
				'next_escape_time'	=> 0,
				'status'			=> 0,
			);
			$ret = $DB->update('prison', $data, 'id='.$prison_id);
		}
		// 更改用户是否在监狱字段
		if ($ret) {
			$sql = 'UPDATE user SET in_prison=0 WHERE uid='.$uid;
			$ret = $DB->exeSql($sql);
			if ($ret !== false) {
				$ret = true;
			}
		}
		
		return $ret;
	}
	
	/**
	 * 越狱失败
	 * @param int $uid
	 * @param int $prison_id
	 */
	private static function escapeFailure($uid, $prison_id) 
	{
		global $DB, $L, $G;
		
		$sql = 'SELECT * FROM prison WHERE id='.$prison_id;
		$prisonInfo = $DB->getValue($sql);
		
		// 威胁度有上限
		if ($prisonInfo['nasty_value'] < $G['max_nasty_value']) {
			$prisonInfo['nasty_value']++;
		}
		$data = array(
			'nasty_value'		=> $prisonInfo['nasty_value'],
			'escape_times'		=> $prisonInfo['escape_times'] + 1,
			'next_escape_time'	=> time() + ($prisonInfo['escape_times'] + 1) * $G['escape_failure_add_cd_time'],
		);
		$ret = $DB->update('prison', $data, 'id='.$prison_id);
		
		if ($ret) {
			$ret = $DB->delete('prison_escape', 'id='.$prison_id);
		}
		
		return $ret;
	}
	
}










